package com.bzframework.pro.authorize.token.manager;

import com.bzframework.pro.authorize.constants.RedisConstants;
import com.bzframework.pro.authorize.token.UserToken;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.ReactiveRedisOperations;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.Map;

/**
 * @Author bingzhong
 * @Date 2024/11/24 14:48
 * @Description
 */
@RequiredArgsConstructor
public class RedisUserTokenManager implements UserTokenManager {

    private final ReactiveRedisOperations<String, String> redisOperations;


    private static final Duration tokenExpireTime = Duration.ofHours(2);

    @Override
    public Mono<UserToken> getUserToken(String token) {
        return redisOperations.opsForHash()
                              .entries(RedisConstants.getRedisKey(RedisConstants.USER_TOKEN, token))
                              .collectMap(Map.Entry::getKey, Map.Entry::getValue)
                              .flatMap(map -> {
                                  if (map.isEmpty()) {
                                      return Mono.empty();
                                  }
                                  String userId = String.valueOf(map.get("userId"));
                                  String token0 = String.valueOf(map.get("token"));
                                  String signInTime = String.valueOf(map.get("signInTime"));
                                  String role = String.valueOf(map.get("role"));
                                  return Mono.just(UserToken.of(userId, token0, signInTime, role));
                              });
    }

    @Override
    public Mono<Boolean> refreshToken(String token) {
        return redisOperations.expire(RedisConstants.getRedisKey(RedisConstants.USER_TOKEN, token), tokenExpireTime);
    }

    @Override
    public Mono<Boolean> hasToken(String token) {
        return redisOperations.hasKey(RedisConstants.getRedisKey(RedisConstants.USER_TOKEN, token));
    }

    @Override
    public Mono<Long> removeToken(String token) {
        return redisOperations.delete(RedisConstants.getRedisKey(RedisConstants.USER_TOKEN, token));
    }
}
